package comlookupd

import (
	"gitee.com/liukexing/mqbroker/core/driver/component"
	"gitee.com/liukexing/mqbroker/core/server/pubsub"
	"gitee.com/liukexing/mqbroker/core/typedef"
	"time"
)

func GetTaskInfo() map[string]typedef.TaskInfo {
	TaskBootStrap()
	return map[string]typedef.TaskInfo{
		"FindRegister::@every 1m": typedef.TaskInfo{
			Name:   "注册节点查询",
			Handle: FindRegisterTask,
			Arg:    nil,
		},
		"ComReg::@every 2m": typedef.TaskInfo{
			Name:   "模块注册",
			Handle: ComRegTask,
			Arg:    nil,
		},
		"HealthCheck::@every 1m": typedef.TaskInfo{
			Name:   "健康检查",
			Handle: HealthTickTask,
			Arg:    nil,
		},
		"ComSync::@every 1m": typedef.TaskInfo{
			Name:   "模块同步",
			Handle: ComSyncTask,
			Arg:    nil,
		},
	}
}

func TaskBootStrap() {
	go func() {
		time.Sleep(time.Second)
		FindRegisterTask(nil)
		time.Sleep(time.Second)
		FindRegisterTask(nil)
	}()
}

func FindRegisterTask(arg map[string]interface{}) error {
	if reqid, err := component.FindRegister(Config.Info); !err {
		ReqMap.Store(reqid, typedef.MsgReceiver{Handle: "FindRegister", Stamp: time.Now(), Mutex: true, TimeOut: time.Minute})
	}
	return nil
}

func ComRegTask(arg map[string]interface{}) error {
	if time.Now().Sub(LastTick) > time.Minute*2 {
		FindMap.Range(func(key, value interface{}) bool {
			pubsub.CommandMsgPub(Config.Info.ID, key.(string), "Register", map[string]interface{}{"info": Config.Info})
			return false
		})
	}
	return nil
}

func HealthTickTask(arg map[string]interface{}) error {
	ComMap.Range(func(key, value interface{}) bool {
		if reqid, err := pubsub.CommandMsgPub(Config.Info.ID, key.(string), "Health", nil); !err {
			ReqMap.Store(reqid, typedef.MsgReceiver{Handle: "Health", Stamp: time.Now()})
		}
		return true
	})
	return nil
}

func ComSyncTask(arg map[string]interface{}) error {
	FindMap.Range(func(k, v interface{}) bool {
		if k == Config.Info.ID {
			return true
		}
		ComMap.Range(func(key, value interface{}) bool {
			if time.Now().Sub(value.(typedef.ComInfo).LastUpdate) > time.Minute*10 {
				ComMap.Delete(key)
				return true
			}
			pubsub.ComputeMsgPub(Config.Info.ID, k.(string), map[string]interface{}{
				"Update": map[string]interface{}{
					"msgtype": "component",
					"key":     key,
					"data":    value,
				},
			})
			return true
		})
		ConfigMap.Range(func(key, value interface{}) bool {
			for id, c := range value.(map[string]interface{}) {
				pubsub.ComputeMsgPub(Config.Info.ID, k.(string), map[string]interface{}{
					"Update": map[string]interface{}{
						"msgtype": "config",
						"module":  key,
						"id":      id,
						"config":  c,
					},
				})
			}
			return true
		})
		return true
	})
	return nil
}
